#ifndef DATAFILEREADER_H
#define DATAFILEREADER_H

#include <QObject>
#include "common.h"

typedef std::string  String;

////////////////////////////////////////////////////////////////
//双精度点结构
typedef struct _DPoint
{
    _DPoint(double X, double Y)
    {
        x = X;
        y = Y;
    }
    double x = 0.0;
    double y = 0.0;
}			DPoint;
//双精度点结构指针
typedef std::shared_ptr<DPoint>			PDPoint;


//文件头
typedef struct _DatFileHeader
{
    String sTitle   = "";
    String sVar		= "";
}DatFileHeader;

//zone类型
enum ZoneType
{
    FEquadrilateral,
    FEtriangle
};

//zone结构
typedef struct _ZoneHeader
{
    String sTime		= "";
    int nVertex			= 0;
    int nElement		= 0;
    ZoneType ztZoneType = FEtriangle;
    String sPack		= "";
    String sVarLoc		= "";
}ZoneHeader;
//网格内顶点
typedef struct _FieldVertex : public DPoint
{
    _FieldVertex(double dz, double du, double dv) :DPoint(0.0,0.0)
    {
        Z = dz;
        U = du;
        V = dv;
    }
    double Z;
    double U;
    double V;
}		FieldVertex;
typedef std::shared_ptr<FieldVertex>		PFieldVertex;
typedef std::vector<PFieldVertex>			VecFieldVertex;


//
typedef struct _ZoneData
{
    ZoneHeader zhZoneHeader;
    VecFieldVertex vFieldVertex;
}ZoneData;

typedef std::shared_ptr<ZoneData>	PZoneData;


typedef std::list<PZoneData> ListAllZoneData;
/*
osg::ref_ptr< osg::Vec3Array> v = new osg::Vec3Array;
osg::ref_ptr< osg::DrawElementsUInt> triangle = new  osg::DrawElementsUInt(
            osg::PrimitiveSet::TRIANGLES,0);
*/


////////////////////////////////////////////////////////////////
//文件各段位置信息
typedef		size_t			POS;

typedef struct _ZonePos
{
    POS start = 0;
    POS end = 0;
}ZonePos;
//坐标点区位置
typedef struct _VertexPos : public ZonePos
{
}VertexPos;
//三角形索引区位置
typedef struct _TriIndexPos : public ZonePos
{
}TriIndexPos;
//数据区位置
typedef struct _FieldDataZonePos : public ZonePos
{
}FieldDataZonePos;
typedef std::shared_ptr<FieldDataZonePos> PFieldDataZonePos;
//所有数据区位置
typedef std::vector<PFieldDataZonePos> VecFieldDataZonePos;
typedef struct _AllZonePos
{
    VertexPos   vertexPos;
    TriIndexPos trindexPos;
    VecFieldDataZonePos vfieldatazonePos;
}AllZonePos;


typedef struct Color
{
    int r;
    int g;
    int b;
}Color;



typedef QVector<double> VecMeshVertex;
typedef QVector<uint> VecTriIndex;

typedef struct _Data
{
    //文件头
    DatFileHeader	Header;
    //顶点坐标
    VecMeshVertex   vMeshVertex;
    //三角形索引
    VecTriIndex     vTriIndex;
    //field数据
    ListAllZoneData ldata;
}Data;

////////////////////////////////////////////////////////////////

class dataFileReader
{
public:
    dataFileReader();
public:
    void SetFileName(const String sFileName);

    void ReadFile(void);


    void GetVertex(osg::ref_ptr<osg::Vec3Array> vertex);
    void GetIndice(osg::ref_ptr<osg::DrawElementsUInt> indice);
    void GetColor(osg::ref_ptr<osg::Vec4Array> color);
protected:
    //获得文件头
    POS SetFileHeader(String& sfile);
    //多线程读文件函数
    void GetAllPos(String& sSour, POS pos);
    //顶点数据
    void SetThreadMeshVertex(String& sfile, POS pos);
    std::thread ThreadMeshvertex(String& sfile, POS& pos);
    //索引数组
    void SetThreadTriIndex(String& sfile, POS pos);
    std::thread ThreadTriIndex(String& sfile, POS& pos);

    //第一组field数据
    void SetThreadFirstFieldVertex(String& sfile, POS pos);
    std::thread ThreadFirstFieldVertex(String& sfile, POS& pos);
    //其他组field数据
    void SetThreadFieldVertex(String& sfile, POS pos);
    std::thread ThreadOtherFieldVerteies(String& sfile, POS& pos);


protected:

    POS SetTitle(String& sSour, String& sDes);
    POS SetVar(String& sSour, POS pos, String& svar);
    POS SetDate(String& sSour, POS pos, String& sDate);
    POS SetN(String& sSour, POS pos, int& n);
    POS SetE(String& sSour, POS pos, int& e);
    POS SetDateNE(String& sSour, POS pos, String& sData, int& n, int& e);
    POS SetZoneType(String& sSour, POS pos, ZoneType& type, String& sPack);
    POS SetVarLocation(String& sSour, POS pos, String& sLoc);

private:
    QString sName;
    uchar* pFile;// 内存映射文件指针
    Data alldata;
    AllZonePos allPos;

    float minDepth;
    float maxDepth;

};

#endif // DATAFILEREADER_H
